package com.fulihui.wgj.service.reply;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.fulihui.common.builder.rpc.RpcResultBuilder;
import com.fulihui.common.conv.BeanConv;
import com.fulihui.common.enums.SubReplyTypeEnum;
import com.fulihui.common.enums.SubReplyUseTypeEnum;
import com.fulihui.common.error.Errors;
import com.fulihui.common.error.InvokeServiceException;
import com.fulihui.common.request.rpc.AppRequest;
import com.fulihui.common.result.rpc.BaseResult;
import com.fulihui.common.result.rpc.SimpleResult;
import com.fulihui.common.util.Base64Utils;
import com.fulihui.common.util.ConditionValidator;
import com.fulihui.wgj.dal.mybatis.domain.WxMaterial;
import com.fulihui.wgj.dal.mybatis.domain.WxRegion;
import com.fulihui.wgj.dal.mybatis.domain.WxSubscribeReplyRule;
import com.fulihui.wgj.dal.mybatis.repository.WxMaterialRepository;
import com.fulihui.wgj.dal.mybatis.repository.WxRegionRepository;
import com.fulihui.wgj.dal.mybatis.repository.WxSubscribeReplyRuleRepository;
import com.fulihui.wgj.facade.dto.WxMaterialDTO;
import com.fulihui.wgj.facade.dto.WxSubscribeReplyRuleDTO;
import com.fulihui.wgj.facade.dto.WxSubscribeReplyRulePreDTO;
import com.fulihui.wgj.facade.request.PrimaryKeyRequest;
import com.fulihui.wgj.facade.request.reply.ReplyRuleEnableOrDisableRequest;
import com.fulihui.wgj.facade.request.reply.WxSubscribeReplyRuleQueryRequest;
import com.fulihui.wgj.facade.request.reply.WxSubscribeReplyRuleSaveRequest;
import com.fulihui.wgj.facade.request.reply.WxSubscribeReplyRuleUpdateRequest;
import com.fulihui.wgj.facade.service.reply.WxSubscribeReplyService;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author wang_wx
 * @date 2018-07-03
 */
@Component
@Service(interfaceClass = WxSubscribeReplyService.class, version = "1.0.0")
public class WxSubscribeReplyServiceImpl implements WxSubscribeReplyService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WxSubscribeReplyServiceImpl.class);

    @Autowired
    WxSubscribeReplyRuleRepository wxSubscribeReplyRuleRepository;

    @Autowired
    WxMaterialRepository wxMaterialRepository;

    @Autowired
    WxRegionRepository wxRegionRepository;

    @Override
    public SimpleResult<List<WxSubscribeReplyRuleDTO>> queryReplyRule(WxSubscribeReplyRuleQueryRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        List<WxSubscribeReplyRuleDTO> wxSubscribeReplyRuleDTOS = Lists.newArrayList();
        List<WxSubscribeReplyRule> replyRules = wxSubscribeReplyRuleRepository.queryByExample(buildExample(request));
        if (!CollectionUtils.isEmpty(replyRules)) {
            replyRules.stream().forEach(wxSubscribeReplyRule -> {
                WxSubscribeReplyRuleDTO replyRuleDTO = BeanConv.copy(wxSubscribeReplyRule, WxSubscribeReplyRuleDTO.class);
                // 区域转中文
                String province = replyRuleDTO.getProvince();
                if (StringUtils.isNotBlank(province)) {
                    List<String> provinceStrList = Lists.newArrayList();
                    Iterable<String> split = Splitter.on(",").split(province);
                    split.forEach(provinceId -> {
                        WxRegion provinceWxRegion = wxRegionRepository.queryWxRegionByRid(provinceId);
                        if (Objects.nonNull(provinceWxRegion)) {
                            provinceStrList.add(provinceWxRegion.getName());
                        }
                    });
                    String provinceStr = Joiner.on("，").join(provinceStrList);
                    replyRuleDTO.setProvinceStr(provinceStr);
                }
                if (SubReplyTypeEnum.text.getValue() == replyRuleDTO.getReplyType()) {
                    // 文本内容需要进行解码 emoji
                    replyRuleDTO.setReplyContent(Base64Utils.decode(replyRuleDTO.getReplyContent()));
                } else {
                    // 不是文本内容 查询素材信息 填充content
                    String mediaId = replyRuleDTO.getReplyContent();
                    if (StringUtils.isNotBlank(mediaId)) {
                        WxMaterial wxMaterial = wxMaterialRepository.queryById(mediaId);
                        if (Objects.nonNull(wxMaterial)) {
                            WxMaterialDTO materialDTO = BeanConv.copy(wxMaterial, WxMaterialDTO.class);
                            replyRuleDTO.setReplyContent(JSONObject.toJSONString(materialDTO));
                        }
                    }
                }
                wxSubscribeReplyRuleDTOS.add(replyRuleDTO);
            });
        }
        return RpcResultBuilder.succSimple(wxSubscribeReplyRuleDTOS);
    }

    /**
     * 组装条件
     *
     * @param request
     * @return
     */
    Example buildExample(WxSubscribeReplyRuleQueryRequest request) {
        Example example = new Example(WxSubscribeReplyRule.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("appId", request.getAppId());
        if (Objects.nonNull(request.getUseType())) {
            criteria.andEqualTo("useType", request.getUseType());
        }
        return example;
    }

    @Override
    public SimpleResult<List<WxSubscribeReplyRuleDTO>> queryReplyRuleByAppIdUseful(AppRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        List<WxSubscribeReplyRuleDTO> wxSubscribeReplyRuleDTOS = Lists.newArrayList();
        List<WxSubscribeReplyRule> replyRules = wxSubscribeReplyRuleRepository.queryByAppIdAndUseful(request.getAppId());
        if (!CollectionUtils.isEmpty(replyRules)) {
            replyRules.stream().forEach(wxSubscribeReplyRule -> {
                WxSubscribeReplyRuleDTO replyRuleDTO = BeanConv.copy(wxSubscribeReplyRule, WxSubscribeReplyRuleDTO.class);
                if (SubReplyTypeEnum.text.getValue() == replyRuleDTO.getReplyType()) {
                    // 文本内容需要进行解码 emoji
                    replyRuleDTO.setReplyContent(Base64Utils.decode(replyRuleDTO.getReplyContent()));
                }
                wxSubscribeReplyRuleDTOS.add(replyRuleDTO);
            });
        }
        return RpcResultBuilder.succSimple(wxSubscribeReplyRuleDTOS);
    }

    @Override
    public BaseResult updateReplyRuleById(WxSubscribeReplyRuleUpdateRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxSubscribeReplyRule replyRule = BeanConv.copy(request, WxSubscribeReplyRule.class);
        replyRule.setGmtModified(new Date());
        if (SubReplyTypeEnum.text.getValue() == replyRule.getReplyType()) {
            // 文本内容需要进行编码 emoji
            replyRule.setReplyContent(Base64Utils.encode(replyRule.getReplyContent()));
        }
        Integer count = wxSubscribeReplyRuleRepository.updateSelective(replyRule);
        return count > 0 ? RpcResultBuilder.succ() : RpcResultBuilder.fail(Errors.Commons.UPDATE_FAILED);
    }

    @Override
    public BaseResult deleteReplyRuleById(PrimaryKeyRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        Integer count;
        count = wxSubscribeReplyRuleRepository.deleteById(request.getId());
        return count > 0 ? RpcResultBuilder.succ() : RpcResultBuilder.fail(Errors.Commons.DELETE_FAILED);
    }

    @Override
    public BaseResult saveReplyRule(WxSubscribeReplyRuleSaveRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxSubscribeReplyRule subscribeReplyRule = BeanConv.copy(request, WxSubscribeReplyRule.class);
        // 默认回复只允许一条
        if (SubReplyUseTypeEnum.DEFAULT.getValue() == request.getUseType().intValue()) {
            List<WxSubscribeReplyRule> wxSubscribeReplyRules = wxSubscribeReplyRuleRepository.queryByAppIdAndUseType(subscribeReplyRule.getAppId(), SubReplyUseTypeEnum.DEFAULT.getValue());
            if (!CollectionUtils.isEmpty(wxSubscribeReplyRules)) {
                return RpcResultBuilder.fail(Errors.WxSubscribeReplyError.RECORD_ALREADY_EXISTS);
            }
        }
        if (SubReplyTypeEnum.text.getValue() == subscribeReplyRule.getReplyType()) {
            // 文本内容需要进行编码 emoji
            subscribeReplyRule.setReplyContent(Base64Utils.encode(subscribeReplyRule.getReplyContent()));
        }
        Integer count = wxSubscribeReplyRuleRepository.saveSelective(subscribeReplyRule);
        return count > 0 ? RpcResultBuilder.succ() : RpcResultBuilder.fail(Errors.Commons.SAVE_FAILED);
    }

    @Override
    public BaseResult enableOrDisable(ReplyRuleEnableOrDisableRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxSubscribeReplyRule exist = wxSubscribeReplyRuleRepository.queryById(request.getId());
        if (Objects.isNull(exist)) {
            return RpcResultBuilder.fail(Errors.Commons.RECORD_NOT_EXISTS);
        }
        if (exist.getUseful().intValue() == request.getUseful().intValue()) {
            return RpcResultBuilder.fail(50001, "已经是启用或者禁用状态");
        }
        WxSubscribeReplyRule replyRuleUpdate = new WxSubscribeReplyRule();
        replyRuleUpdate.setId(request.getId());
        replyRuleUpdate.setUseful(request.getUseful());
        replyRuleUpdate.setGmtModified(new Date());
        Integer count = wxSubscribeReplyRuleRepository.updateSelective(replyRuleUpdate);
        return count > 0 ? RpcResultBuilder.succ() : RpcResultBuilder.fail(Errors.Commons.UPDATE_FAILED);
    }

    @Override
    public SimpleResult<WxSubscribeReplyRuleDTO> queryRuleById(PrimaryKeyRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxSubscribeReplyRule subscribeReplyRule = wxSubscribeReplyRuleRepository.queryById(request.getId());
        WxSubscribeReplyRuleDTO replyRuleDTO = null;
        if (Objects.nonNull(subscribeReplyRule)) {
            replyRuleDTO = BeanConv.copy(subscribeReplyRule, WxSubscribeReplyRuleDTO.class);
            if (SubReplyTypeEnum.text.getValue() == replyRuleDTO.getReplyType()) {
                // 文本内容需要进行解码 emoji
                replyRuleDTO.setReplyContent(Base64Utils.decode(replyRuleDTO.getReplyContent()));
            } else {
                // 不是文本内容 查询素材信息 填充content
                String mediaId = replyRuleDTO.getReplyContent();
                if (StringUtils.isNotBlank(mediaId)) {
                    WxMaterial wxMaterial = wxMaterialRepository.queryById(mediaId);
                    if (Objects.nonNull(wxMaterial)) {
                        WxMaterialDTO materialDTO = BeanConv.copy(wxMaterial, WxMaterialDTO.class);
                        replyRuleDTO.setReplyContent(JSONObject.toJSONString(materialDTO));
                        replyRuleDTO.setMediaId(mediaId);
                    }
                }
            }
        }
        return RpcResultBuilder.succSimple(replyRuleDTO);
    }

    @Override
    public SimpleResult<WxSubscribeReplyRulePreDTO> queryRulePreview(PrimaryKeyRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxSubscribeReplyRule subscribeReplyRule = wxSubscribeReplyRuleRepository.queryById(request.getId());
        WxSubscribeReplyRulePreDTO content = new WxSubscribeReplyRulePreDTO();
        content.setReplyType(subscribeReplyRule.getReplyType());
        if (Objects.nonNull(subscribeReplyRule)) {
            if (SubReplyTypeEnum.text.getValue() == subscribeReplyRule.getReplyType()) {
                // 文本内容需要进行解码 emoji
                content.setReplyContent(Base64Utils.decode(subscribeReplyRule.getReplyContent()));
            } else {
                // 不是文本内容 查询素材信息 填充content
                String mediaId = subscribeReplyRule.getReplyContent();
                if (StringUtils.isNotBlank(mediaId)) {
                    WxMaterial wxMaterial = wxMaterialRepository.queryById(mediaId);
                    if (Objects.nonNull(wxMaterial)) {
                        WxMaterialDTO materialDTO = BeanConv.copy(wxMaterial, WxMaterialDTO.class);
                        content.setReplyContent(JSONObject.toJSONString(materialDTO));
                    }
                }
            }
        }
        return RpcResultBuilder.succSimple(content);
    }
}
